﻿using lib;
using System;
using System.IO;
using System.Net.Sockets;
using System.Runtime.Serialization.Formatters.Binary;

namespace Server
{
    class Client
    {
        private BinaryFormatter formatter = new BinaryFormatter();
        private TcpClient _client;
        private bool _firstMeasurement, bconnected, notconnected;
        public lib.TestResult TestResultFile { get; private set; }
        internal ClientHandler clientHandle;
        private Server server;
        public SecureConnectionServer secureConnection { get; set; }
        
        public Client(Server s, SecureConnectionServer sc)
        {
            _firstMeasurement = true;
            bconnected = false;
            notconnected = true;
            TestResultFile = new lib.TestResult();
            server = s;
            secureConnection = sc;
        }

        // Handle client (save or load file depending on the input data).
        public void Handle(Object obj)
        {
            // Read data and save or load file here.
            clientHandle = obj as ClientHandler;
            _client = clientHandle.Client;
            String[] split = new String[3];

            if (secureConnection == null)
            {
                secureConnection = new SecureConnectionServer(_client, Server.getCertificate());
            }

            while (true)
            {
                try
                {
                    split = secureConnection.ReadObjectAsString().Split(':');
                }
                catch 
                {
                    Console.WriteLine("ERROR: Connection to client {0} lost", clientHandle.patientnaam);
                    if(ClientHandler.tcpDoc != null)
                        server.getDocClient().secureConnection.SendObject("removepatient:" + clientHandle.patientID);
                    secureConnection.ClosesslStream();
                    server.getClients().Remove(this);
                    SaveFile();
                    break;
                }
                if (split[0].Equals("measurement"))
                {
                    HandleMeasurement();
                }
                else if (split[0].Equals("chat"))
                {
                    server.getDocClient().secureConnection.SendObject("chat:" + clientHandle.patientnaam + ":" + split[1]);
                    Console.WriteLine("chat from: " +clientHandle.patientnaam +" to doc. Message = "+ split[1] );
                }
            }
        }

        private void HandleMeasurement()
        {
            Object measurementObject = secureConnection.ReadObject();
            
            // If the object should be saved and send, do so. Else ignore the object.
            try
            {
                if (clientHandle.patientID == server.getDocClient().selectedID)
                {
                    server.getDocClient().secureConnection.SendObject("handlefullmeasurements:" + clientHandle.patientnaam + ":" + TestResultFile.getLast().getString());
                }
            }
            catch 
            {
                
            }
            if (!_firstMeasurement)
            {
                lib.MeasuredValues measurement = measurementObject as lib.MeasuredValues;
                TestResultFile.AddMeasuredValues(measurement);
                if (ClientHandler.tcpDoc != null)
                {
                    server.getDocClient().secureConnection.SendObject("singlemeasurement:" + measurement.time.ToString() + ":" + clientHandle.patientID + ":" + measurement.heartBeat + ":" + measurement.currentPower);
                }
                else
                {
                    if (notconnected)
                    {
                        secureConnection.SendObject("chat: doctor is not connected");
                        notconnected = false;
                        bconnected = false;
                    }
                }
            }

            else
            {
                lib.MeasuredValues measurement = measurementObject as lib.MeasuredValues;
                TestResultFile.AddMeasuredValues(measurement);
                TestResultFile.Tijd = DateTime.Now;
                TestResultFile.Patientnr = clientHandle.patientID.ToString();
                TestResultFile.Patientnaam = clientHandle.patientnaam;
                _firstMeasurement = false;
                if (ClientHandler.tcpDoc != null)
                {
                    server.getDocClient().secureConnection.SendObject("singlemeasurement:" + measurement.time.ToString() + ":" + clientHandle.patientID + ":" + measurement.heartBeat + ":" + measurement.currentPower);
                }
            }
            if (bconnected == false)
            {
                if (ClientHandler.tcpDoc != null)
                {
                    server.getDocClient().secureConnection.SendObject("newpatient:" + clientHandle.patientnaam + ":" + clientHandle.patientID);
                    bconnected = true;
                    secureConnection.SendObject("chat: doctor is connected");
                    notconnected = true;
                }
            }
        }

        private void SaveFile()
        {
            String filename = TestResultFile.Patientnr + TestResultFile.Patientnaam + TestResultFile.Tijd.Year + "-" + TestResultFile.Tijd.Month + "-" + TestResultFile.Tijd.Day + "-" + TestResultFile.Tijd.Hour + "-" + TestResultFile.Tijd.Minute;

            try
            {
                FileStream fs = File.Create("SavedFiles/" + filename + ".pedofile");
                formatter.Serialize(fs, TestResultFile);
                fs.Close();
                Console.WriteLine(@"File stored: " + filename);
            }
            catch (Exception e)
            {
                Console.WriteLine(@"Exception = " + e.Message);
            }
        }

        public int getID()
        {
            return clientHandle.patientID;
        }


    }
}


